package org.example.http;

import org.example.util.JavaHttpRequest;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public abstract class AbstractHttpRequest implements HttpRequest {

    protected static SSLSocketFactory socketFactory;

    static {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        }};
        try {
            SSLContext sc = SSLContext.getInstance("TLS", "SunJSSE");
            sc.init(null, trustAllCerts, new SecureRandom());
            AbstractHttpRequest.socketFactory = sc.getSocketFactory();
        } catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException e) {
            throw new RuntimeException("https信息证书注册失败!");
        }
    }

    /**
     * 请求头
     */
    protected final List<Header> headers = new ArrayList<>(16);

    @Override
    public HttpRequest addHeader(String name, String value) {
        headers.add(new SimpleHeader(name, value));
        return this;
    }

    @Override
    public HttpRequest addHeader(Map<String, String> headers) {
        headers.forEach(this::addHeader);
        return this;
    }

    @Override
    public HttpRequest addHeader(Header header) {
        if (null == header) {
            return this;
        }
        for (int i = 0; i < this.headers.size(); ++i) {
            Header current = this.headers.get(i);
            if (current.getName().equalsIgnoreCase(header.getName())) {
                this.headers.set(i, header);
                return this;
            }
        }
        this.headers.add(header);
        return this;
    }

    @Override
    public HttpRequest addHeader(List<Header> headers) {
        if (null != headers && !headers.isEmpty()) {
            headers.forEach(this::addHeader);
        }
        return this;
    }
}
